<!DOCTYPE html>
<html>
<head>
    

    

    



    <meta charset="utf-8">
    
    
    
    <title>Activiti | 尼古拉斯-鱼丸博客 | 喝酒、吃肉、不赌</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    
    <meta name="theme-color" content="#3F51B5">
    
    
    <meta name="keywords" content="Activiti">
    <meta name="description" content="摘自：三分钟了解activiti工作流(http://www.it165.net/pro/html/201504/37443.html)摘自：activiti工作流学习(http://blog.csdn.net/zwk626542417/article/details/46592471) 什么是Activiti?  工作流是将一组任务组织起来以完成某个经营过程：定义了任务的触发顺序和触发条件，每个">
<meta name="keywords" content="Activiti">
<meta property="og:type" content="article">
<meta property="og:title" content="Activiti">
<meta property="og:url" content="http://fish_08.oschina.io/2017/08/17/activity/index.html">
<meta property="og:site_name" content="尼古拉斯-鱼丸博客">
<meta property="og:description" content="摘自：三分钟了解activiti工作流(http://www.it165.net/pro/html/201504/37443.html)摘自：activiti工作流学习(http://blog.csdn.net/zwk626542417/article/details/46592471) 什么是Activiti?  工作流是将一组任务组织起来以完成某个经营过程：定义了任务的触发顺序和触发条件，每个">
<meta property="og:updated_time" content="2017-08-18T06:14:29.826Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Activiti">
<meta name="twitter:description" content="摘自：三分钟了解activiti工作流(http://www.it165.net/pro/html/201504/37443.html)摘自：activiti工作流学习(http://blog.csdn.net/zwk626542417/article/details/46592471) 什么是Activiti?  工作流是将一组任务组织起来以完成某个经营过程：定义了任务的触发顺序和触发条件，每个">
    
        <link rel="alternative" href="/atom.xml" title="尼古拉斯-鱼丸博客" type="application/atom+xml">
    
    <link rel="shortcut icon" href="/favicon.ico">
    <link rel="stylesheet" href="/css/style.css?v=1.6.7">
    <script>window.lazyScripts=[]</script>
</head>

<body>
    <div id="loading" class="active"></div>

    <aside id="menu" class="hide" >
  <div class="inner flex-row-vertical">
    <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menu-off">
        <i class="icon icon-lg icon-close"></i>
    </a>
    <div class="brand-wrap">
      <div class="brand">
        <a href="/" class="avatar waves-effect waves-circle waves-light">
          <img src="/img/avatar.jpg">
        </a>
        <hgroup class="introduce">
          <h5 class="nickname">于亮</h5>
          <a href="mailto:136214289@qq.com" title="136214289@qq.com" class="mail">136214289@qq.com</a>
        </hgroup>
      </div>
    </div>
    <div class="scroll-wrap flex-col">
      <ul class="nav">
        
            <li class="waves-block waves-effect">
              <a href="/"  >
                <i class="icon icon-lg icon-home"></i>
                主页
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/archives"  >
                <i class="icon icon-lg icon-archives"></i>
                文档
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/tags"  >
                <i class="icon icon-lg icon-tags"></i>
                标签
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="http://git.oschina.net/fish_08" target="_blank" >
                <i class="icon icon-lg icon-github"></i>
                Github
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="http://weibo.com/2837335591/profile?rightmod=1&wvr=6&mod=personinfo" target="_blank" >
                <i class="icon icon-lg icon-weibo"></i>
                Weibo
              </a>
            </li>
        
            <li class="waves-block waves-effect">
              <a href="/custom"  >
                <i class="icon icon-lg icon-link"></i>
                测试
              </a>
            </li>
        
      </ul>
    </div>
  </div>
</aside>

    <main id="main">
        <header class="top-header" id="header">
    <div class="flex-row">
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light on" id="menu-toggle">
          <i class="icon icon-lg icon-navicon"></i>
        </a>
        <div class="flex-col header-title ellipsis">Activiti</div>
        
        <div class="search-wrap" id="search-wrap">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
                <i class="icon icon-lg icon-chevron-left"></i>
            </a>
            <input type="text" id="key" class="search-input" autocomplete="off" placeholder="输入感兴趣的关键字">
            <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="search">
                <i class="icon icon-lg icon-search"></i>
            </a>
        </div>
        
        
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="menuShare">
            <i class="icon icon-lg icon-share-alt"></i>
        </a>
        
    </div>
</header>
<header class="content-header post-header">

    <div class="container fade-scale">
        <h1 class="title">Activiti</h1>
        <h5 class="subtitle">
            
                <time datetime="2017-08-17T02:23:56.000Z" itemprop="datePublished" class="page-time">
  2017-08-17
</time>


            
        </h5>
    </div>

    

</header>


<div class="container body-wrap">
    
    <aside class="post-widget">
        <nav class="post-toc-wrap" id="post-toc">
            <h4>TOC</h4>
            <ol class="post-toc"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#什么是Activiti"><span class="post-toc-number">1.</span> <span class="post-toc-text">什么是Activiti?</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Activiti相关概念"><span class="post-toc-number">2.</span> <span class="post-toc-text">Activiti相关概念?</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Activity学习demo-helloWorld"><span class="post-toc-number">3.</span> <span class="post-toc-text">Activity学习demo helloWorld</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#流程定义"><span class="post-toc-number">4.</span> <span class="post-toc-text">流程定义</span></a></li></ol>
        </nav>
    </aside>
    
<article id="post-activity"
  class="post-article article-type-post fade" itemprop="blogPost">

    <div class="post-card">
        <h1 class="post-card-title">Activiti</h1>
        <div class="post-meta">
            <time class="post-time" title="2017年08月17日 10:23" datetime="2017-08-17T02:23:56.000Z"  itemprop="datePublished">2017-08-17</time>

            


            
<span id="busuanzi_container_page_pv" title="文章总阅读量" style='display:none'>
    <i class="icon icon-eye icon-pr"></i><span id="busuanzi_value_page_pv"></span>
</span>


            

        </div>
        <div class="post-content" id="post-content" itemprop="postContent">
            <p>摘自：三分钟了解activiti工作流(<a href="http://www.it165.net/pro/html/201504/37443.html" target="_blank" rel="external">http://www.it165.net/pro/html/201504/37443.html</a>)<br>摘自：activiti工作流学习(<a href="http://blog.csdn.net/zwk626542417/article/details/46592471" target="_blank" rel="external">http://blog.csdn.net/zwk626542417/article/details/46592471</a>)</p>
<h3 id="什么是Activiti"><a href="#什么是Activiti" class="headerlink" title="什么是Activiti?"></a>什么是Activiti?</h3><p>  工作流是将一组任务组织起来以完成某个经营过程：定义了任务的触发顺序和触发条件，每个任务可以由一个或多个软件系统完成，也可以由一个或一组人完成，还可以由一个或多个人与软件系统协作完成。</p>
<h3 id="Activiti相关概念"><a href="#Activiti相关概念" class="headerlink" title="Activiti相关概念?"></a>Activiti相关概念?</h3><p><strong>WfMC(WorkflowManagementCoalition)</strong><br>  工作流和业务流程管理的推广学者，PG、顾问、分析师、大学和研究团队的全球性的组织</p>
<p><strong>WfMS(WorkflowManagement System)</strong><br>  工作流管理系统，它完成了工作量的定义和管理，并按照在系统中预先定义好的工作流规则进行工作流实例的执行的软件系统。工作流管理系统不是企业的业务系统，而是为企业的业务系统的运行提供了一个软件的支撑环境。WfMS被用来定义、管理和执行工作流程，它的目标是管理工作的流程以确保工作在正确的时间被期望的人员所执行。同时也可以在自动化进行的业务过程中插入人工的执行和干预。</p>
<p><strong>WfMS与工作流框架</strong><br>  WfMS我一般习惯于称它为工作流框架，常见的工作流框Activiti、JBPM、OSWorkflow、ActiveBPEL、YAWL等。<br><strong>工作流引擎</strong><br>  个人觉得直接理解工作流引擎概念有点难度，我们可以先通过了解工作流引擎的职责再反过来理解工作流引擎，工作流引擎一般都做两件事情：<br>  1.定义流程，也就是给我们提供某种规范来定义规则，以及如何定义一个流程的这种规范，同时我们可以根据工作流引擎提供的相关概念来定义更为复杂的流程，这就是工作流引擎做的第一件事叫做定义流程。<br>  2.执行流程，也就是工作流引擎需要解释这个规则，还要负责流程，它相当于流程的调度者，监控每个流程的执行情况，并将流程操作发往下一步，或者根据条件休眠或终止流程的这么一个过程就叫做执行流程。<br>  了解完工作流引擎的这两个职责，我相信对于什么是工作流引擎一定已经有了一定的认识了，我们在用一句稍微有点官方的话来总结一下工作流引擎，工作流引擎为我们提供相关规则概念的定义，给我们提供了相关的API来调用这个引擎去执行流程。流程的操作实际上就是工作流引擎提供相关的api我们去调用它。</p>
<p><strong>工作流框架与工作流引擎</strong><br>  上面我们提及了常见了几个工作流框架，其中现在的Activiti和JBPM5.0之前的版本都是基于ProcessEngine 工作流引擎的工作流框架；JBPM5.0开始是基于DroolsFlow为工作流引擎的工作流框架；其中OSWorkflow是以工作流引擎命名的工作流框架，所以OSWorkflow是基于OSWorkflow工作流引擎的工作流框架；ActiveBPEL是基于工作流BPEL引擎的工作流框架…….<br>  到这里关于工作流的相关概念就介绍完了，接下来我们先了解一下我们的主角activiti的前世今生。</p>
<p><strong>Activiti前世今生</strong><br>   Activiti 的创始人是  Tom Baeyens 说到Tom Baeyens 就不能不提他与jbpm的渊源。TomBaeyens 是 jBPM 的创始人，在 2002年，Tom Baeyens创建了基于状态机原理的jBPM流程引擎。jBPM经过了JBoss和Redhat公司之后，发展到了 jBPM 4。由于jBPM使用的是 GPL开源协议，并且与JBoss和Redhat公司的其他产品线结合的越来越紧密，对jBPM在更广泛的范围使用形成了阻碍。JBoss内部对jBPM未来版本的架构实现产生了严重的意见分歧，在2005年 Tom Baeyens离开了JBoss公司加入了Alfresco 公司，创建了使用Apache based-license V2的、独立于Alfresco产品的开源流程产品Activiti 。Activiti在2010年3月份开始启动，到了2010年12月份正式发布第一个版本，新的基于jBPM4的开源工作流系统Activiti 5.0  ！所以说Activiti5是在jBPM 3、jBPM 4的基础上发展而来的，是原jBPM 的延续。</p>
<p><strong>Activiti 与jBPM 5的比较</strong><br>   jBPM 5则与之前的jBPM3、jBPM 4没有太大关联，且舍弃了备受推崇的PVM（流程虚拟机）思想，转而选择jBoss自身产品DroolsFlow作为流程引擎的核心实现，工作流最为重要的“人机交互”任务（类似于审批活动）则由单独的一块“Human Task Service”附加到DroolsFlow上实现，任务的查询、处理等行为通过Apache Mina异步通信机制完成。</p>
<table>
<thead>
<tr>
<th style="text-align:left">序号</th>
<th style="text-align:left">技术组成</th>
<th style="text-align:left">Activiti</th>
<th style="text-align:left">jBPM5</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">1</td>
<td style="text-align:left">数据库持久层ORM</td>
<td style="text-align:left">MyBatis3</td>
<td style="text-align:left">Hibernate3</td>
</tr>
<tr>
<td style="text-align:left">2</td>
<td style="text-align:left">持久化标准</td>
<td style="text-align:left">无</td>
<td style="text-align:left">JPA规范</td>
</tr>
<tr>
<td style="text-align:left">3</td>
<td style="text-align:left">事务管理</td>
<td style="text-align:left">MyBatis机制/spring事务控制</td>
<td style="text-align:left">Bitronix，基于JTA事务管理</td>
</tr>
<tr>
<td style="text-align:left">4</td>
<td style="text-align:left">数据库连接方式</td>
<td style="text-align:left">Jdbc/DataSource</td>
<td style="text-align:left">Jdbc/DataSource</td>
</tr>
<tr>
<td style="text-align:left">5</td>
<td style="text-align:left">支持数据库</td>
<td style="text-align:left">Oracle、SQL Server、MySQL等多数数据库</td>
<td style="text-align:left">Oracle、SQL Server、MySQL等多数数据库</td>
</tr>
<tr>
<td style="text-align:left">6</td>
<td style="text-align:left">设计模式</td>
<td style="text-align:left">Command模式、观察者模式等</td>
<td style="text-align:left">无</td>
</tr>
<tr>
<td style="text-align:left">7</td>
<td style="text-align:left">内部服务通讯</td>
<td style="text-align:left">Service间通过API调用</td>
<td style="text-align:left">基于Apache Mina异步通讯</td>
</tr>
<tr>
<td style="text-align:left">8</td>
<td style="text-align:left">集成接口</td>
<td style="text-align:left">SOAP、Mule、RESTful</td>
<td style="text-align:left">消息通讯</td>
</tr>
<tr>
<td style="text-align:left">9</td>
<td style="text-align:left">支持的流程格式</td>
<td style="text-align:left">BPMN2、xPDL、jPDL等</td>
<td style="text-align:left">目前仅只支持BPMN2 xml</td>
</tr>
<tr>
<td style="text-align:left">10</td>
<td style="text-align:left">引擎核心</td>
<td style="text-align:left">PVM（流程虚拟机）</td>
<td style="text-align:left">Drools</td>
</tr>
<tr>
<td style="text-align:left">11</td>
<td style="text-align:left">技术前身</td>
<td style="text-align:left">jBPM3、jBPM4</td>
<td style="text-align:left">Drools Flow</td>
</tr>
<tr>
<td style="text-align:left">12</td>
<td style="text-align:left">所属公司</td>
<td style="text-align:left">Alfresco</td>
<td style="text-align:left">jBoss.org</td>
</tr>
</tbody>
</table>
<p><strong>工作流优点</strong><br> 工作流系统，实现了工作流程的自动化，提高了企业运营效率、改善企业资源利用、提高企业运作的灵活性和适应性、提高量化考核业务处理的效率、减少浪费（时间就是金钱）。<br> 手工处理工作流程，一方面无法对整个流程状况进行有效跟踪、了解，另一方面难免会出现人为的失误和时间上的延时导致效率低下，特别是无法进行量化统计，不利于查询、报表及绩效评估。</p>
<p><strong>JAVA开发者为什么要学习Activity工作流</strong><br> 在Java领域，JBPM和Activiti是两个主流的工作流系统，而activiti的出现无疑将会取代JBPM（Activiti的开发者就是从Jbpm开发者出来的）。</p>
<p><strong>Activity工作流学习要点</strong><br><strong>1.1个插件</strong><br> 在开发工具中安装Activiti插件，可以再开发工具中绘制activity工作流图</p>
<p><strong>2.1个引擎</strong><br>ProcessEngine对象,Activiti工作流引擎。这个是Activiti工作核心，负责生成流程运行时各种实例及数据、监控和管理流程的运行。<br>所有的操作都是从获取引擎开始的，所以一般会把引擎作为全局变量。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div><div class="line">144</div><div class="line">145</div><div class="line">146</div><div class="line">147</div><div class="line">148</div><div class="line">149</div><div class="line">150</div><div class="line">151</div><div class="line">152</div><div class="line">153</div><div class="line">154</div><div class="line">155</div><div class="line">156</div><div class="line">157</div><div class="line">158</div><div class="line">159</div><div class="line">160</div><div class="line">161</div><div class="line">162</div><div class="line">163</div><div class="line">164</div><div class="line">165</div><div class="line">166</div><div class="line">167</div><div class="line">168</div><div class="line">169</div><div class="line">170</div><div class="line">171</div><div class="line">172</div><div class="line">173</div><div class="line">174</div><div class="line">175</div><div class="line">176</div><div class="line">177</div><div class="line">178</div><div class="line">179</div><div class="line">180</div><div class="line">181</div><div class="line">182</div><div class="line">183</div><div class="line">184</div><div class="line">185</div><div class="line">186</div><div class="line">187</div><div class="line">188</div><div class="line">189</div><div class="line">190</div><div class="line">191</div><div class="line">192</div></pre></td><td class="code"><pre><div class="line"> </div><div class="line"> ProcessEngine processEngine =ProcessEngines.getDefaultProcessEngine();</div><div class="line"></div><div class="line">``` </div><div class="line">**3.1个配置文件**</div><div class="line">activiti.cfg.xml,Activiti核心配置文件，配置流程引擎创建工具的基本参数和数据库连接池参数</div><div class="line"></div><div class="line"></div><div class="line">**4.5中数据库表**</div><div class="line">Activiti的后台是有数据库的支持，所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。用途也和服务的API对应。</div><div class="line">ACT_RE_*: <span class="string">'RE'</span>表示repository。 这个前缀的表包含了流程定义和流程静态资源（图片，规则，等等）。</div><div class="line">ACT_RU_*: <span class="string">'RU'</span>表示runtime。 这些运行时的表，包含流程实例，任务，变量，异步任务，等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据，在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。</div><div class="line">ACT_ID_*: <span class="string">'ID'</span>表示identity。 这些表包含身份信息，比如用户，组等等。</div><div class="line">ACT_HI_*: <span class="string">'HI'</span>表示<span class="built_in">history</span>。 这些表包含历史数据，比如历史流程实例，变量，任务等等。</div><div class="line">ACT_GE_*: 通用数据，用于不同场景下，如存放资源文件。</div><div class="line"></div><div class="line">**5.23张表**</div><div class="line">activiti.cfg.xml,Activiti核心配置文件，配置流程引擎创建工具的基本参数和数据库连接池参数</div><div class="line"></div><div class="line">act_re_deployment</div><div class="line">act_re_model</div><div class="line">act_re_procdef</div><div class="line"></div><div class="line">act_ru_event_subscr</div><div class="line">act_ru_execution</div><div class="line">act_ru_identitylink</div><div class="line">act_ru_job</div><div class="line">act_ru_task</div><div class="line">act_ru_variable</div><div class="line"></div><div class="line">act_id_group</div><div class="line">act_id_info</div><div class="line">act_id_membership</div><div class="line">act_id_user</div><div class="line"></div><div class="line">act_hi_actinst</div><div class="line">act_hi_attachment</div><div class="line">act_hi_comment</div><div class="line">act_hi_detail</div><div class="line">act_hi_identitylink</div><div class="line">act_hi_procinst</div><div class="line">act_hi_taskinst</div><div class="line">act_hi_varinst</div><div class="line"></div><div class="line">act_ge_bytearray</div><div class="line">act_ge_property</div><div class="line"></div><div class="line">**6.5类service**</div><div class="line">不同的Service类对应不同的功能。</div><div class="line">例:TaskService，是activiti的任务服务类。可以从这个类中获取任务的信息。</div><div class="line">   HistoryService，则是activiti的查询历史信息的类。在一个流程执行完成后，这个对象为我们提供查询历史信息。</div><div class="line"></div><div class="line">**7.7类基本操作**</div><div class="line">设计流程图（各类组件，如连线、用户任务、网关）</div><div class="line">流程定义增删改查</div><div class="line">流程变量增删改查</div><div class="line">启动流程定义</div><div class="line">任务增删改查</div><div class="line">完成任务</div><div class="line">历史信息查询</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">### Activity学习,创建activiti表</span></div><div class="line"></div><div class="line">**1.使用代码来创建activiti工作流的表**</div><div class="line">``` bash</div><div class="line">// 使用代码创建工作流需要的23张表  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">createTable</span></span>() &#123;  </div><div class="line">    // 工作流引擎的全部配置  </div><div class="line">    ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration  </div><div class="line">            .createStandaloneProcessEngineConfiguration();  </div><div class="line">  </div><div class="line">    // 链接数据的配置  </div><div class="line">    processEngineConfiguration.setJdbcDriver(<span class="string">"com.mysql.jdbc.Driver"</span>);  </div><div class="line">    processEngineConfiguration  </div><div class="line">            .setJdbcUrl(<span class="string">"jdbc:mysql://localhost:3306/activiti1?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf8"</span>);  </div><div class="line">    processEngineConfiguration.setJdbcUsername(<span class="string">"root"</span>);  </div><div class="line">    processEngineConfiguration.setJdbcPassword(<span class="string">"123456"</span>);  </div><div class="line">   </div><div class="line">    /* </div><div class="line">     * public static final String DB_SCHEMA_UPDATE_FALSE = <span class="string">"false"</span>; </div><div class="line">     * 不能自动创建表，需要表存在 public static final String DB_SCHEMA_UPDATE_CREATE_DROP </div><div class="line">     * = <span class="string">"create-drop"</span>; 先删除表再创建表 public static final String </div><div class="line">     * DB_SCHEMA_UPDATE_TRUE = <span class="string">"true"</span>;如果表不存在，自动创建表 </div><div class="line">     */  </div><div class="line">    //如果表不存在，自动创建表  </div><div class="line">    processEngineConfiguration  </div><div class="line">            .setDatabaseSchemaUpdate(processEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);  </div><div class="line">    // 工作流的核心对象，ProcessEnginee对象  </div><div class="line">    ProcessEngine processEngine = processEngineConfiguration  </div><div class="line">            .buildProcessEngine();  </div><div class="line">    System.out.println(processEngine);  </div><div class="line">  </div><div class="line">  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">``` </div><div class="line"></div><div class="line"> 代码执行完毕，我们通过navicat查看数据库会发现，创建了一个新的数据库activiti1，并且还有23张表。+act_evt_log  act_procdef_info</div><div class="line"></div><div class="line">**2使用配置文件来创建activiti的表**</div><div class="line">在类路径下创建Activiti.cfg.xml文件，文件内容为：</div><div class="line">``` bash</div><div class="line">&lt;beans xmlns=<span class="string">"http://www.springframework.org/schema/beans"</span>  </div><div class="line">    xmlns:context=<span class="string">"http://www.springframework.org/schema/context"</span> xmlns:tx=<span class="string">"http://www.springframework.org/schema/tx"</span>  </div><div class="line">    xmlns:xsi=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span>  </div><div class="line">    xsi:schemaLocation=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  </span></div><div class="line">http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  </div><div class="line">http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"&gt;  </div><div class="line">  </div><div class="line">  </div><div class="line">  &lt;bean id=<span class="string">"processEngineConfiguration"</span>  </div><div class="line">       class=<span class="string">"org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"</span>&gt;  </div><div class="line">       &lt;!-- 连接数据的配置 --&gt;  </div><div class="line">       &lt;property name=<span class="string">"jdbcDriver"</span> value=<span class="string">"com.mysql.jdbc.Driver"</span>&gt;&lt;/property&gt;  </div><div class="line">       &lt;property name=<span class="string">"jdbcUrl"</span>  </div><div class="line">           value=<span class="string">"jdbc:mysql://localhost:3306/activiti1?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf8"</span>&gt;&lt;/property&gt;  </div><div class="line">       &lt;property name=<span class="string">"jdbcUsername"</span> value=<span class="string">"root"</span>&gt;&lt;/property&gt;  </div><div class="line">       &lt;property name=<span class="string">"jdbcPassword"</span> value=<span class="string">"123456"</span>&gt;&lt;/property&gt;  </div><div class="line">       &lt;!-- 没有表创建表 --&gt;  </div><div class="line">       &lt;property name=<span class="string">"databaseSchemaUpdate"</span> value=<span class="string">"true"</span>&gt;&lt;/property&gt;  </div><div class="line">   &lt;/bean&gt;  </div><div class="line">  </div><div class="line">&lt;/beans&gt;  </div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">/** </div><div class="line"> * 使用配置文件来创建数据库中的表 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">createTable_2</span></span>() &#123;  </div><div class="line">    //通过让工作流引擎的全部配置对象来执行配置文件中的内容来创建流程引擎对象  </div><div class="line">    ProcessEngine processEngine = ProcessEngineConfiguration  </div><div class="line">            .createProcessEngineConfigurationFromResource(  </div><div class="line">                    <span class="string">"activiti.cfg.xml"</span>).buildProcessEngine();  </div><div class="line">    System.out.println(<span class="string">"processEngine"</span> + processEngine);  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">``` </div><div class="line"></div><div class="line">连接数据库url写法：</div><div class="line"> </div><div class="line">   无论是通过代码还是通过xml文件来创建工作流的表，里面都涉及到一个知识点就是mysql的url的写法，我们进行下小结：</div><div class="line">   <span class="comment">#autoReconnect当数据库连接丢失时是否自动连接，取值true/false 缺省为false</span></div><div class="line">   <span class="comment">#maxReconnects如果autoReconnect为true,此参数为重试次数，缺省为3次 </span></div><div class="line">   <span class="comment">#initialTimeout如果autoReconnect为true,此参数为重新连接前等待的秒数缺省为2</span></div><div class="line">   <span class="comment">#maxRows设置查询时返回的行数，0表示全部缺省为0</span></div><div class="line">   <span class="comment">#useUnicode是否使用unicode输出，true/false缺省为false</span></div><div class="line">   <span class="comment">#characterEncoding如果useUnicode,该参数制定encoding类型，建议使用utf8缺省为无</span></div><div class="line">   <span class="comment">#createDatabaseIfNotExist当JDBC连接指定数据库,如果此数据库不存在,此参数值为true时，则自动创建此数据库</span></div><div class="line"></div><div class="line">  ``` bash</div><div class="line">jdbc:mysql://localhost:3306/ourmysql?  </div><div class="line">createDatabaseIfNotExist=<span class="literal">true</span>&amp;  </div><div class="line">amp;useUnicode=<span class="literal">true</span>&amp;  </div><div class="line">amp;characterEncoding=utf8&amp;  </div><div class="line">amp;autoReconnect=<span class="literal">true</span>&amp;  </div><div class="line">amp;useLocalSessionState=<span class="literal">true</span>  </div><div class="line"></div><div class="line">  ``` </div><div class="line"></div><div class="line"><span class="comment">### Activity学习,核心对象ProcessEngine</span></div><div class="line">  数据库里的表创建完毕，接下来我们讲述activiti里面的核心对象ProcessEngine。</div><div class="line">  ProcessEngine类，一般称为流程引擎类，没错，这个流程引擎就是我们上一篇文章中提到的流程引擎，它是activiti中最核心的类，并且这个类是线程安全的，所有的线程和请求都可以使用同一个ProcessEngine对象，其它常用类几乎也都是由它而来的。</div><div class="line">**得到ProcessEngine对象**</div><div class="line">方式1：使用classpath根目录下的默认配置文件jbpm.cfg.xml创建一个单例的ProcessEngine </div><div class="line">  ``` bash</div><div class="line">ProcessEngineprocessEngine = ProcessEngines.getDefaultProcessEngine();  </div><div class="line"></div><div class="line">  ``` </div><div class="line">方式2：指定其他位置:配置文件，如src根目录config包下的my-jbpm-cfg.xml。</div><div class="line">   ``` bash</div><div class="line">   @Test</div><div class="line">    public void <span class="function"><span class="title">createTable_2</span></span>() &#123;</div><div class="line">        //通过让工作流引擎的全部配置对象来执行配置文件中的内容来创建流程引擎对象</div><div class="line">        ProcessEngine processEngine = ProcessEngineConfiguration</div><div class="line">                .createProcessEngineConfigurationFromResource(</div><div class="line">                        <span class="string">"my-jbpm-cfg.xml"</span>).buildProcessEngine();</div><div class="line">        System.out.println(<span class="string">"processEngine"</span> + processEngine);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">  ``` </div><div class="line"></div><div class="line">**得到各个Service**</div><div class="line"> RepositoryService</div><div class="line"> RepositoryService是管理流程定义的仓库服务的接口。</div><div class="line"></div><div class="line">   ``` bash</div><div class="line">	RepositoryService repositoryService = processEngine.getRepositoryService();</div></pre></td></tr></table></figure></p>
<p>RuntimeService<br>RuntimeService是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息，如执行管理，包括启动、推进、删除流程实例等操作。<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">RuntimeServiceruntimeService = processEngine.getRuntimeService();</div></pre></td></tr></table></figure></p>
<p>TaskService<br>TaskService是activiti的任务服务类。可以从这个类中获取任务的信息。<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">TaskServicetaskservice = processEngine.getTaskService();</div></pre></td></tr></table></figure></p>
<p>HistoryService<br>HistoryService 是activiti的查询历史信息的类。在一个流程执行完成后，这个对象为我们提供查询历史信息。<br>   <figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">HistoryServicehistoryService = processEngine.getHistoryService();</div></pre></td></tr></table></figure></p>
<h3 id="Activity学习demo-helloWorld"><a href="#Activity学习demo-helloWorld" class="headerlink" title="Activity学习demo helloWorld"></a>Activity学习demo helloWorld</h3><p>第一步流程设计画出业务流程<br>我们通过流程设计器就可以拖拖拽拽出我们的流程，同时设置相关属性，保存后会生成两个文件，分别是helloworld.bpmn和helloworld.png.</p>
<p>第二步部署流程定义<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line">/** </div><div class="line"> * 部署流程定义 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">deploymentProcessDefinition</span></span>() &#123;  </div><div class="line">    //创建核心引擎对象  </div><div class="line">    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();  </div><div class="line">    Deployment deployment = processEngine.getRepositoryService()// 与流程定义和部署对象相关的service  </div><div class="line">            .createDeployment()// 创建一个部署对象  </div><div class="line">            .name(<span class="string">"helloworld入门程序"</span>)// 添加部署的名称  </div><div class="line">            .addClasspathResource(<span class="string">"diagrams/helloworld.bpmn"</span>)// classpath的资源中加载，一次只能加载  </div><div class="line">                                                                // 一个文件  </div><div class="line">            .addClasspathResource(<span class="string">"diagrams/helloworld.png"</span>)// classpath的资源中加载，一次只能加载  </div><div class="line">                                                            // 一个文件  </div><div class="line">            .deploy();// 完成部署  </div><div class="line">    System.out.println(<span class="string">"部署ID:"</span> + deployment.getId());  </div><div class="line">    System.out.println(<span class="string">"部署名称："</span> + deployment.getName());  </div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>第三步 启动流程实例<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">/** </div><div class="line"> * 启动流程实例 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">startProcessInstance</span></span>() &#123;  </div><div class="line">    // 流程定义的key  </div><div class="line">    String processDefinitionKey = <span class="string">"HelloWorld"</span>;  </div><div class="line">    ProcessInstance pi = processEngine.getRuntimeService()// 于正在执行的流程实例和执行对象相关的Service  </div><div class="line">            .startProcessInstanceByKey(processDefinitionKey);// 使用流程定义的key启动流程实例，key对应hellworld.bpmn文件中id的属性值，使用key值启动，默认是按照最新版本的流程定义启动  </div><div class="line">    System.out.println(<span class="string">"流程实例ID:"</span> + pi.getId());// 流程实例ID 101  </div><div class="line">    System.out.println(<span class="string">"流程定义ID:"</span> + pi.getProcessDefinitionId()); // 流程定义ID HelloWorld:1:4  </div><div class="line">    &#125;</div></pre></td></tr></table></figure></p>
<p>第四步查询当前办理人的个人任务<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line">/** </div><div class="line"> * 查询当前人的个人任务 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findMyPersonTask</span></span>() &#123;  </div><div class="line">    String assignee = <span class="string">"张三"</span>;  </div><div class="line">    List&lt;Task&gt; list = processEngine.getTaskService()// 与正在执行的认为管理相关的Service  </div><div class="line">            .createTaskQuery()// 创建任务查询对象  </div><div class="line">            .taskAssignee(assignee)// 指定个人认为查询，指定办理人  </div><div class="line">            .list();  </div><div class="line">  </div><div class="line">   <span class="keyword">if</span> (list != null &amp;&amp; list.size() &gt; 0) &#123;  </div><div class="line">   <span class="keyword">for</span> (Task task:list) &#123;  </div><div class="line">    System.out.println(<span class="string">"任务ID:"</span>+task.getId());  </div><div class="line">    System.out.println(<span class="string">"任务名称:"</span>+task.getName());  </div><div class="line">    System.out.println(<span class="string">"任务的创建时间"</span>+task);  </div><div class="line">    System.out.println(<span class="string">"任务的办理人:"</span>+task.getAssignee());  </div><div class="line">    System.out.println(<span class="string">"流程实例ID:"</span>+task.getProcessInstanceId());  </div><div class="line">    System.out.println(<span class="string">"执行对象ID:"</span>+task.getExecutionId());  </div><div class="line">    System.out.println(<span class="string">"流程定义ID:"</span>+task.getProcessDefinitionId());  </div><div class="line">    System.out.println(<span class="string">"#################################"</span>);  </div><div class="line">  &#125;  </div><div class="line">  &#125;  </div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>第五步 完成任务<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">/** </div><div class="line"> * 完成我的任务 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">completeMyPersonTask</span></span>()&#123;  </div><div class="line">    //任务Id  </div><div class="line">    String taskId=<span class="string">"104"</span>;  </div><div class="line">    processEngine.getTaskService()//与正在执行的认为管理相关的Service  </div><div class="line">            .complete(taskId);  </div><div class="line">    System.out.println(<span class="string">"完成任务:任务ID:"</span>+taskId);  </div><div class="line">  </div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<h3 id="流程定义"><a href="#流程定义" class="headerlink" title="流程定义"></a>流程定义</h3><p><strong>流程定义是什么</strong><br>  ProcessDefinition（流程定义）就是一个流程的步骤说明，比如我们接下来要说的这个流程，申请人王三发起提交申请，李四作为部门经理进行审批，审批完成后，此申请到达下一级总经理王五，进行审批。就这么整个流程说明其实就是流程定义，不过在Activiti中整个流程定义是以helloworld.bpmn与helloworld.png格式存在的。<br>  在上一篇文章中我们只是稍微提了下，关于helloworld.bpmn是在流程设计器中拖拖拽拽形成的，其实还可以通过在配置文件中进行配置，具体的图形我已经放到了上一篇文章中了，现在我就将我配置好的helloworld.bpmn配置文件展示给大家：<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div></pre></td><td class="code"><pre><div class="line">&lt;?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?&gt;  </div><div class="line">&lt;definitions xmlns=<span class="string">"http://www.omg.org/spec/BPMN/20100524/MODEL"</span> xmlns:xsi=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span> xmlns:xsd=<span class="string">"http://www.w3.org/2001/XMLSchema"</span> xmlns:activiti=<span class="string">"http://activiti.org/bpmn"</span> xmlns:bpmndi=<span class="string">"http://www.omg.org/spec/BPMN/20100524/DI"</span> xmlns:omgdc=<span class="string">"http://www.omg.org/spec/DD/20100524/DC"</span> xmlns:omgdi=<span class="string">"http://www.omg.org/spec/DD/20100524/DI"</span> typeLanguage=<span class="string">"http://www.w3.org/2001/XMLSchema"</span> expressionLanguage=<span class="string">"http://www.w3.org/1999/XPath"</span> targetNamespace=<span class="string">"http://www.activiti.org/test"</span>&gt;  </div><div class="line">  &lt;process id=<span class="string">"HelloWorld"</span> name=<span class="string">"HelloWorldProcess"</span> isExecutable=<span class="string">"true"</span>&gt;  </div><div class="line">    &lt;startEvent id=<span class="string">"startevent1"</span> name=<span class="string">"Start"</span>&gt;&lt;/startEvent&gt;  </div><div class="line">    &lt;endEvent id=<span class="string">"endevent1"</span> name=<span class="string">"End"</span>&gt;&lt;/endEvent&gt;  </div><div class="line">    &lt;userTask id=<span class="string">"usertask1"</span> name=<span class="string">"提交申请"</span> activiti:assignee=<span class="string">"张三"</span>&gt;&lt;/userTask&gt;  </div><div class="line">    &lt;userTask id=<span class="string">"usertask2"</span> name=<span class="string">"审批【部门经理】"</span> activiti:assignee=<span class="string">"李四"</span>&gt;&lt;/userTask&gt;  </div><div class="line">    &lt;userTask id=<span class="string">"usertask3"</span> name=<span class="string">"审批【总经理】"</span> activiti:assignee=<span class="string">"王五"</span>&gt;&lt;/userTask&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow1"</span> sourceRef=<span class="string">"startevent1"</span> targetRef=<span class="string">"usertask1"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow2"</span> sourceRef=<span class="string">"usertask1"</span> targetRef=<span class="string">"usertask2"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow3"</span> sourceRef=<span class="string">"usertask2"</span> targetRef=<span class="string">"usertask3"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow4"</span> sourceRef=<span class="string">"usertask3"</span> targetRef=<span class="string">"endevent1"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">  &lt;/process&gt;  </div><div class="line">  &lt;bpmndi:BPMNDiagram id=<span class="string">"BPMNDiagram_HelloWorld"</span>&gt;  </div><div class="line">    &lt;bpmndi:BPMNPlane bpmnElement=<span class="string">"HelloWorld"</span> id=<span class="string">"BPMNPlane_HelloWorld"</span>&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"startevent1"</span> id=<span class="string">"BPMNShape_startevent1"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"35.0"</span> width=<span class="string">"35.0"</span> x=<span class="string">"320.0"</span> y=<span class="string">"50.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"endevent1"</span> id=<span class="string">"BPMNShape_endevent1"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"35.0"</span> width=<span class="string">"35.0"</span> x=<span class="string">"320.0"</span> y=<span class="string">"430.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"usertask1"</span> id=<span class="string">"BPMNShape_usertask1"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"55.0"</span> width=<span class="string">"105.0"</span> x=<span class="string">"285.0"</span> y=<span class="string">"120.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"usertask2"</span> id=<span class="string">"BPMNShape_usertask2"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"55.0"</span> width=<span class="string">"105.0"</span> x=<span class="string">"285.0"</span> y=<span class="string">"240.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"usertask3"</span> id=<span class="string">"BPMNShape_usertask3"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"55.0"</span> width=<span class="string">"105.0"</span> x=<span class="string">"285.0"</span> y=<span class="string">"350.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow1"</span> id=<span class="string">"BPMNEdge_flow1"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"85.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"120.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow2"</span> id=<span class="string">"BPMNEdge_flow2"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"175.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"240.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow3"</span> id=<span class="string">"BPMNEdge_flow3"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"295.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"350.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow4"</span> id=<span class="string">"BPMNEdge_flow4"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"405.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"337.0"</span> y=<span class="string">"430.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">    &lt;/bpmndi:BPMNPlane&gt;  </div><div class="line">  &lt;/bpmndi:BPMNDiagram&gt;  </div><div class="line">&lt;/definitions&gt;</div></pre></td></tr></table></figure></p>
<p><strong>流程定义的CRUD</strong><br><strong>部署流程定义</strong><br>  在进行流程定义的操作之前，先要将流程定义进行部署，部署流程定义的方式有两种：<br>  1.部署流程定义的helloworld.bpmn与helloworld.png两个文件<br>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div><div class="line">144</div><div class="line">145</div><div class="line">146</div><div class="line">147</div><div class="line">148</div><div class="line">149</div><div class="line">150</div><div class="line">151</div><div class="line">152</div><div class="line">153</div><div class="line">154</div><div class="line">155</div><div class="line">156</div><div class="line">157</div><div class="line">158</div><div class="line">159</div><div class="line">160</div><div class="line">161</div><div class="line">162</div><div class="line">163</div><div class="line">164</div><div class="line">165</div><div class="line">166</div><div class="line">167</div><div class="line">168</div><div class="line">169</div><div class="line">170</div><div class="line">171</div><div class="line">172</div><div class="line">173</div><div class="line">174</div><div class="line">175</div><div class="line">176</div><div class="line">177</div><div class="line">178</div><div class="line">179</div><div class="line">180</div><div class="line">181</div><div class="line">182</div><div class="line">183</div><div class="line">184</div><div class="line">185</div><div class="line">186</div><div class="line">187</div><div class="line">188</div><div class="line">189</div><div class="line">190</div><div class="line">191</div><div class="line">192</div><div class="line">193</div><div class="line">194</div><div class="line">195</div><div class="line">196</div><div class="line">197</div><div class="line">198</div><div class="line">199</div><div class="line">200</div><div class="line">201</div><div class="line">202</div><div class="line">203</div><div class="line">204</div><div class="line">205</div><div class="line">206</div><div class="line">207</div><div class="line">208</div><div class="line">209</div><div class="line">210</div><div class="line">211</div><div class="line">212</div><div class="line">213</div><div class="line">214</div><div class="line">215</div><div class="line">216</div><div class="line">217</div><div class="line">218</div><div class="line">219</div><div class="line">220</div><div class="line">221</div><div class="line">222</div><div class="line">223</div><div class="line">224</div><div class="line">225</div><div class="line">226</div><div class="line">227</div><div class="line">228</div><div class="line">229</div><div class="line">230</div><div class="line">231</div><div class="line">232</div><div class="line">233</div><div class="line">234</div><div class="line">235</div><div class="line">236</div><div class="line">237</div><div class="line">238</div><div class="line">239</div><div class="line">240</div><div class="line">241</div><div class="line">242</div><div class="line">243</div><div class="line">244</div><div class="line">245</div><div class="line">246</div><div class="line">247</div><div class="line">248</div><div class="line">249</div><div class="line">250</div><div class="line">251</div><div class="line">252</div><div class="line">253</div><div class="line">254</div><div class="line">255</div><div class="line">256</div><div class="line">257</div><div class="line">258</div><div class="line">259</div><div class="line">260</div><div class="line">261</div><div class="line">262</div><div class="line">263</div><div class="line">264</div><div class="line">265</div><div class="line">266</div><div class="line">267</div><div class="line">268</div><div class="line">269</div><div class="line">270</div><div class="line">271</div><div class="line">272</div><div class="line">273</div><div class="line">274</div><div class="line">275</div><div class="line">276</div><div class="line">277</div><div class="line">278</div><div class="line">279</div><div class="line">280</div><div class="line">281</div><div class="line">282</div><div class="line">283</div><div class="line">284</div><div class="line">285</div><div class="line">286</div><div class="line">287</div><div class="line">288</div><div class="line">289</div><div class="line">290</div><div class="line">291</div><div class="line">292</div><div class="line">293</div><div class="line">294</div><div class="line">295</div><div class="line">296</div><div class="line">297</div><div class="line">298</div><div class="line">299</div><div class="line">300</div><div class="line">301</div><div class="line">302</div><div class="line">303</div><div class="line">304</div><div class="line">305</div><div class="line">306</div><div class="line">307</div><div class="line">308</div><div class="line">309</div><div class="line">310</div><div class="line">311</div><div class="line">312</div><div class="line">313</div><div class="line">314</div><div class="line">315</div><div class="line">316</div><div class="line">317</div><div class="line">318</div><div class="line">319</div><div class="line">320</div><div class="line">321</div><div class="line">322</div><div class="line">323</div><div class="line">324</div><div class="line">325</div><div class="line">326</div><div class="line">327</div><div class="line">328</div><div class="line">329</div><div class="line">330</div><div class="line">331</div><div class="line">332</div><div class="line">333</div><div class="line">334</div><div class="line">335</div><div class="line">336</div><div class="line">337</div><div class="line">338</div><div class="line">339</div><div class="line">340</div><div class="line">341</div><div class="line">342</div><div class="line">343</div><div class="line">344</div><div class="line">345</div><div class="line">346</div><div class="line">347</div><div class="line">348</div><div class="line">349</div><div class="line">350</div><div class="line">351</div><div class="line">352</div><div class="line">353</div><div class="line">354</div><div class="line">355</div><div class="line">356</div><div class="line">357</div><div class="line">358</div><div class="line">359</div><div class="line">360</div></pre></td><td class="code"><pre><div class="line">  public void <span class="function"><span class="title">deoploymentProcessDefinition_classpath</span></span>() &#123;  </div><div class="line">    Deployment deployment = processEngine.getRepositoryService() // 与流程定义和部署对象相关的service  </div><div class="line">            .createDeployment()// 创建一个部署对象  </div><div class="line">            .name(<span class="string">"流程定义"</span>)// 添加部署的名称  </div><div class="line">            .addClasspathResource(<span class="string">"diagrams/helloworld.bpmn"</span>)// 从classpath的资源中加载，一次只能加载一个文件  </div><div class="line">            .addClasspathResource(<span class="string">"diagrams/helloworld.png"</span>)// 从classpath的资源中加载，一次只能加载一个文件  </div><div class="line">            .deploy();// 完成部署  </div><div class="line">    System.out.println(<span class="string">"部署ID："</span> + deployment.getId());  </div><div class="line">    System.out.println(<span class="string">"部署名称:"</span> + deployment.getName());  </div><div class="line"></div><div class="line">  ``` </div><div class="line">  运行结果：</div><div class="line">    部署ID：301</div><div class="line">    部署名称:流程定义</div><div class="line"></div><div class="line"> 2.将helloworld.bpmn与helloworld.png压缩成zip进行部署</div><div class="line">  ``` bash</div><div class="line"> /** </div><div class="line"> * 部署流程定义 zip </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">deploymentProcessDefinition_zip</span></span>() &#123;  </div><div class="line">    InputStream <span class="keyword">in</span> = this.getClass().getClassLoader()  </div><div class="line">            .getResourceAsStream(<span class="string">"diagrams/helloworld.zip"</span>);  </div><div class="line">    ZipInputStream zipInputStream = new ZipInputStream(<span class="keyword">in</span>);  </div><div class="line">    Deployment deployment = processEngine.getRepositoryService()// 与流程定义和部署对象相关的service  </div><div class="line">            .createDeployment()// 创建一个部署对象  </div><div class="line">            .name(<span class="string">"流程定义"</span>)// 添加部署  </div><div class="line">            .addZipInputStream(zipInputStream)// 指定zip格式的文件完成部署  </div><div class="line">            .deploy();// 完成部署  </div><div class="line">    System.out.println(<span class="string">"部署ID："</span> + deployment.getId());  </div><div class="line">    System.out.println(<span class="string">"部署名称:"</span> + deployment.getName());  </div><div class="line">  </div><div class="line">&#125;  </div><div class="line">  ``` </div><div class="line">  运行结果：</div><div class="line">   部署ID：401</div><div class="line">   部署名称:流程定义</div><div class="line"> </div><div class="line">我们将上面部署的过程进行下解释：</div><div class="line">   1)先获取流程引擎对象：在创建时会自动加载classpath下的activiti.cfg.xml</div><div class="line">   2)通过获取的流程引擎对象，通过流程引擎对象获取一个RepositoryService对象（仓库对象）</div><div class="line">   3)由仓库的服务对象产生一个部署对象配置对象，用来封装部署操作的相关配置</div><div class="line">   4)这是一个链式编程，在部署配置对象中设置显示名字，上传流程定义规则文件</div><div class="line">   5)向数据库表中存放流程定义的规则信息</div><div class="line">这些表都是跟部署对象和流程定义相关的表：</div><div class="line">    act_re_deployment存放流程定义的显示名和部署时间，每部署一次增加一条记录；</div><div class="line">    act_re_procdef（存放流程定义的属性信息，部署每个新的流程定义都会在这张表中增加一条记录，需要注意一下的当流程定义的key相同的情况下，使用的是版本升级；</div><div class="line">    act_ge_bytearray存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录，一条是关于bpmn规则文件的，一条是图片的（如果部署时只指定了bpmn一个文件，activiti会在部署时解析bpmn文件内容自动生成流程图）。两个文件不是很大，都是以二进制形式存储在数据库中。</div><div class="line"> </div><div class="line">**流程定义的查询**</div><div class="line"> 关于流程定义在上面我们已经部署完毕了，在这里我们进行流程定义的查询，查询分成两个，一个是查询所有的流程定义还有一个查询最新版本的流程定义</div><div class="line"> **查看所有的流程定义**</div><div class="line">  ``` bash</div><div class="line"> /** </div><div class="line"> * 查询所有的流程定义 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findProcessDefinition</span></span>() &#123;  </div><div class="line">   List&lt;ProcessDefinition&gt; list = processEngine.getRepositoryService()// 与流程定义和部署对象先相关的service  </div><div class="line">    .createProcessDefinitionQuery()// 创建一个流程定义的查询  </div><div class="line">    /** 指定查询条件，<span class="built_in">where</span>条件 */  </div><div class="line">    // .deploymentId(deploymentId) //使用部署对象ID查询  </div><div class="line">    // .processDefinitionId(processDefinitionId)//使用流程定义ID查询  </div><div class="line">    // .processDefinitionNameLike(processDefinitionNameLike)//使用流程定义的名称模糊查询  </div><div class="line"></div><div class="line">   /* 排序 */  </div><div class="line">   .orderByProcessDefinitionVersion().asc()  </div><div class="line">   // .orderByProcessDefinitionVersion().desc()  </div><div class="line"></div><div class="line">   /* 返回的结果集 */  </div><div class="line">   .list();// 返回一个集合列表，封装流程定义  </div><div class="line">   // .singleResult();//返回惟一结果集  </div><div class="line">   // .count();//返回结果集数量  </div><div class="line">   // .listPage(firstResult, maxResults);//分页查询  </div><div class="line"> </div><div class="line">   <span class="keyword">if</span> (list != null &amp;&amp; list.size() &gt; 0) &#123;  </div><div class="line">   <span class="keyword">for</span> (ProcessDefinition pd : list) &#123;  </div><div class="line">    System.out.println(<span class="string">"流程定义ID:"</span> + pd.getId());// 流程定义的key+版本+随机生成数  </div><div class="line">    System.out.println(<span class="string">"流程定义的名称:"</span> + pd.getName());// 对应helloworld.bpmn文件中的name属性值  </div><div class="line">    System.out.println(<span class="string">"流程定义的key:"</span> + pd.getKey());// 对应helloworld.bpmn文件中的id属性值  </div><div class="line">    System.out.println(<span class="string">"流程定义的版本:"</span> + pd.getVersion());// 当流程定义的key值相同的相同下，版本升级，默认1  </div><div class="line">    System.out.println(<span class="string">"资源名称bpmn文件:"</span> + pd.getResourceName());  </div><div class="line">    System.out.println(<span class="string">"资源名称png文件:"</span> + pd.getDiagramResourceName());  </div><div class="line">    System.out.println(<span class="string">"部署对象ID："</span> + pd.getDeploymentId());  </div><div class="line">    System.out.println(<span class="string">"#########################################################"</span>);  </div><div class="line">  &#125;  </div><div class="line">  &#125;  </div><div class="line">&#125;</div><div class="line"> ``` </div><div class="line"></div><div class="line"> 运行结果：</div><div class="line"></div><div class="line">流程定义ID:HelloWorld:1:304</div><div class="line">流程定义的名称:HelloWorldProcess</div><div class="line">流程定义的key:HelloWorld</div><div class="line">流程定义的版本:1</div><div class="line">资源名称bpmn文件:diagrams/helloworld.bpmn</div><div class="line">资源名称png文件:diagrams/helloworld.png</div><div class="line">部署对象ID：301</div><div class="line"><span class="comment">#########################################################</span></div><div class="line">流程定义ID:HelloWorld:2:404</div><div class="line">流程定义的名称:HelloWorldProcess</div><div class="line">流程定义的key:HelloWorld</div><div class="line">流程定义的版本:2</div><div class="line">资源名称bpmn文件:helloworld.bpmn</div><div class="line">资源名称png文件:helloworld.png</div><div class="line">部署对象ID：401</div><div class="line"><span class="comment">#########################################################</span></div><div class="line"></div><div class="line">从上面我们可以看出，流程定义key值相同的情况下，版本是从1开始逐次升级的，流程定义的id是【key：版本：生成ID】；</div><div class="line"> </div><div class="line">我们对上面代码进行下说明：</div><div class="line"> </div><div class="line">1)流程定义和部署对象相关的Service都是RepositoryService。</div><div class="line">2)创建流程定义查询对象，可以在ProcessDefinitionQuery上设置查询的相关参数</div><div class="line">3)调用ProcessDefinitionQuery对象的list方法，执行查询，获得符合条件的流程定义列表</div><div class="line">4)由运行结果可以看出：Key和Name的值为：bpmn配置文件process节点的id和name的属性值</div><div class="line">5)key属性被用来区别不同的流程定义。</div><div class="line">6)带有特定key的流程定义第一次部署时，version为1。之后每次部署都会在当前最高版本号上加1</div><div class="line">7)Id的值的生成规则为:&#123;processDefinitionKey&#125;:&#123;processDefinitionVersion&#125;:&#123;generated-id&#125;,这里的generated-id是一个自动生成的唯一的数字</div><div class="line">8)重复部署一次，deploymentId的值以一定的形式变化规则act_ge_property表生成</div><div class="line"></div><div class="line">``` bash</div><div class="line"> </div><div class="line"> **查看最新版本的流程定义：  **</div><div class="line">/** </div><div class="line"> * 附加功能，查询最新版本的流程定义 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findLastVersionProcessDefinition</span></span>() &#123;  </div><div class="line">    List&lt;ProcessDefinition&gt; list = processEngine.getRepositoryService()  </div><div class="line">            .createProcessDefinitionQuery()  </div><div class="line">            .orderByProcessDefinitionVersion().asc() // 使用流程定义的版本升序排列  </div><div class="line">            .list();  </div><div class="line">  </div><div class="line">/** </div><div class="line">* Map&lt;String,ProcessDefinition&gt; map集合的key：流程定义的key map集合的value：流程定义的对象 </div><div class="line">* map集合的特点：当map集合key值相同的情况下，后一次的值将替换前一次的值 </div><div class="line">*/  </div><div class="line">Map&lt;String, ProcessDefinition&gt; map = new LinkedHashMap&lt;String, ProcessDefinition&gt;();  </div><div class="line"><span class="keyword">if</span> (list != null &amp;&amp; list.size() &gt; 0) &#123;  </div><div class="line"><span class="keyword">for</span> (ProcessDefinition pd : list) &#123;  </div><div class="line">    map.put(pd.getKey(), pd);  </div><div class="line">&#125;  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">List&lt;ProcessDefinition&gt; pdList = new ArrayList&lt;ProcessDefinition&gt;(  </div><div class="line">    map.values());  </div><div class="line"><span class="keyword">if</span> (pdList != null &amp;&amp; pdList.size() &gt; 0) &#123;  </div><div class="line"><span class="keyword">for</span> (ProcessDefinition pd : pdList) &#123;  </div><div class="line">	   System.out.println(<span class="string">"流程定义ID:"</span> + pd.getId());// 流程定义的key+版本+随机生成数  </div><div class="line">	   System.out.println(<span class="string">"流程定义的名称:"</span> + pd.getName());// 对应helloworld.bpmn文件中的name属性值  </div><div class="line">	   System.out.println(<span class="string">"流程定义的key:"</span> + pd.getKey());// 对应helloworld.bpmn文件中的id属性值  </div><div class="line">	   System.out.println(<span class="string">"流程定义的版本:"</span> + pd.getVersion());// 当流程定义的key值相同的相同下，版本升级，默认1  </div><div class="line">	   System.out.println(<span class="string">"资源名称bpmn文件:"</span> + pd.getResourceName());  </div><div class="line">	   System.out.println(<span class="string">"资源名称png文件:"</span> + pd.getDiagramResourceName());  </div><div class="line">	   System.out.println(<span class="string">"部署对象ID："</span> + pd.getDeploymentId());  </div><div class="line">	   System.out.println(<span class="string">"#########################################################"</span>);  </div><div class="line">&#125;  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">&#125;  </div><div class="line"> </div><div class="line"> </div><div class="line">``` </div><div class="line"> 运行结果：</div><div class="line">    </div><div class="line">流程定义ID:HelloWorld:2:404</div><div class="line">流程定义的名称:HelloWorldProcess</div><div class="line">流程定义的key:HelloWorld</div><div class="line">流程定义的版本:2</div><div class="line">资源名称bpmn文件:helloworld.bpmn</div><div class="line">资源名称png文件:helloworld.png</div><div class="line">部署对象ID：401</div><div class="line"><span class="comment">#########################################################</span></div><div class="line">运行结果可看到我们可以查出最新版本的流程定义，查询与上面的全部查询是一样的，只不过多了一个过滤版本的功能，是用map来做代码很好理解。</div><div class="line"></div><div class="line">**获取流程定义的文件资源**</div><div class="line"> 我们将流程定义部署完毕后，还可以查看流程定义的图片。</div><div class="line">``` bash</div><div class="line"> /** </div><div class="line"> * 查看流程图 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void viewPic() throws IOException &#123;  </div><div class="line">	// 将生产的图片放到文件夹下  </div><div class="line">	String deploymentId = <span class="string">"401"</span>;// TODO  </div><div class="line">	// 获取图片资源名称  </div><div class="line">	List&lt;String&gt; list = processEngine.getRepositoryService()  </div><div class="line">	.getDeploymentResourceNames(deploymentId);  </div><div class="line"></div><div class="line">   // 定义图片资源名称  </div><div class="line">   String resourceName = <span class="string">""</span>;  </div><div class="line">   <span class="keyword">if</span> (list != null &amp;&amp; list.size() &gt; 0) &#123;  </div><div class="line">   <span class="keyword">for</span> (String name : list) &#123;  </div><div class="line">   <span class="keyword">if</span> (name.indexOf(<span class="string">".png"</span>) &gt;= 0) &#123;  </div><div class="line">     resourceName = name;  </div><div class="line">   &#125;  </div><div class="line">  &#125;  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">   // 获取图片的输入流  </div><div class="line">   InputStream <span class="keyword">in</span> = processEngine.getRepositoryService()  .getResourceAsStream(deploymentId, resourceName);  </div><div class="line"></div><div class="line">   File file = new File(<span class="string">"D:/"</span> + resourceName);  </div><div class="line">   // 将输入流的图片写到D盘下  </div><div class="line">   FileUtils.copyInputStreamToFile(<span class="keyword">in</span>, file);  </div><div class="line">&#125;  </div><div class="line">``` </div><div class="line">说明：</div><div class="line">1)deploymentId为流程部署ID</div><div class="line">2)resourceName为act_ge_bytearray表中NAME_列的值</div><div class="line">3)使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称</div><div class="line">4)使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流</div><div class="line">5)最后的有关IO流的操作，使用FileUtils工具的copyInputStreamToFile方法完成流程流程到文件的拷贝，将资源文件以流的形式输出到指定文件夹下</div><div class="line"></div><div class="line"></div><div class="line">**流程定义的删除**</div><div class="line">流程定义的删除，因为流程定义可以启动，所以涉及到一个普通删除和级联删除的情况，如果该流程定义下没有正在运行的流程，则可以用普通删除。如果是有关联的信息，用级联删除。关于删除我们既可以通过部署对象的id删除也可以通过流程定义的key删除，不同是使用id删除的只是一条记录，而使用key删除的是将key相同的所有版本的流程定义全部删除。</div><div class="line"></div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 删除流程定义(删除key相同的所有不同版本的流程定义) </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">delteProcessDefinitionByKey</span></span>() &#123;  </div><div class="line">    // 流程定义的Key  </div><div class="line">    String processDefinitionKey = <span class="string">"HelloWorld"</span>;  </div><div class="line">    // 先使用流程定义的key查询流程定义，查询出所有的版本  </div><div class="line">    List&lt;ProcessDefinition&gt; list = processEngine.getRepositoryService()  </div><div class="line">            .createProcessDefinitionQuery()  </div><div class="line">            .processDefinitionKey(processDefinitionKey)// 使用流程定义的key查询  </div><div class="line">            .list();  </div><div class="line">    // 遍历，获取每个流程定义的部署ID  </div><div class="line">    <span class="keyword">if</span> (list != null &amp;&amp; list.size() &gt; 0) &#123;  </div><div class="line">        <span class="keyword">for</span> (ProcessDefinition pd : list) &#123;  </div><div class="line">            // 获取部署ID  </div><div class="line">            String deploymentId = pd.getDeploymentId();  </div><div class="line">            //      /*  </div><div class="line">            //       * 不带级联的删除， 只能删除没有启动的流程，如果流程启动，就会抛出异常  </div><div class="line">            //       */  </div><div class="line">            //       processEngine.getRepositoryService().deleteDeployment(deploymentId);  </div><div class="line">              </div><div class="line">   /** </div><div class="line">    * 级联删除 不管流程是否启动，都可以删除 </div><div class="line">    */  </div><div class="line">   processEngine.getRepositoryService().deleteDeployment( deploymentId, <span class="literal">true</span>);  </div><div class="line"></div><div class="line">&#125;  </div><div class="line"></div><div class="line">&#125;  </div><div class="line">&#125;  </div><div class="line">``` </div><div class="line"></div><div class="line">说明：</div><div class="line"></div><div class="line">1)因为删除的是流程定义，而流程定义的部署是属于仓库服务的，所以应该先得到RepositoryService</div><div class="line">2)根据流程定义的key先查询出key值相同的所有版本的流程定义，然后获取每个流程定义的部署对象id</div><div class="line">3)利用部署对象id，进行级联删除</div><div class="line">到这里我们就将流程定义的部署、查询、删除介绍完了，关于流程定义的修改其实就是在key值相同的情况下再次部署，让流程定义的版本进行升级，不影响以前的就版本的流程，对于新的流程就会默认使用最新版本的流程定义。</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">### 流程实例</span></div><div class="line">**流程实例（ProcessInstance ）**</div><div class="line">流程实例（ProcessInstance）和上一篇文章中流程定义（ProcessDefinition）的关系，与类和实例对象的关系有点像，ProcessDefinition是整个流程步骤的说明而ProcessInstance就是指流程定义从开始到结束的那个最大的执行路线。</div><div class="line"></div><div class="line">**执行对象（Execution）**</div><div class="line">提到ProcessInstance同时又会出现另一个名词，那就是执行对象（Execution），Execution是按照ProcessDefinition的规则执行的当前的路线，</div><div class="line">如果ProcessDefinition只有一个执行路线的话，那么Execution和ProcessInstance就是完全一样了如果ProcessDefinition中有多个执行路线的话，Execution和ProcessInstance可能是同一个也可能不是同一个。所以得出结论：一个流程中ProcessInstance有且只能有一个，而Execution可以存在多个。</div><div class="line"></div><div class="line">**任务（Task ）**</div><div class="line">任务（Task）应该比较好理解，就是当流程执行到某步骤或某环节时生产的任务信息。</div><div class="line"></div><div class="line"></div><div class="line">**启动流程实例**</div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 启动流程实例 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">startProcessInstance</span></span>() &#123;  </div><div class="line">    // 流程定义的key  </div><div class="line">    String processDefinitionKey = <span class="string">"HelloWorld"</span>;  </div><div class="line">    ProcessInstance pi = processEngine.getRuntimeService()// 与正在执行的流程实例和执行对象相关的Service  </div><div class="line">            .startProcessInstanceByKey(processDefinitionKey);// 使用流程定义的key启动流程实例，key对应HelloWorld.bpmn文件中id的属性值，使用key值启动，默认是按照最新版本的流程定义启动  </div><div class="line">    System.out.println(<span class="string">"流程实例ID:"</span> + pi.getId());  </div><div class="line">    System.out.println(<span class="string">"流程定义ID:"</span> + pi.getProcessDefinitionId());  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">``` </div><div class="line"></div><div class="line">运行结果：</div><div class="line"></div><div class="line">流程实例ID:501</div><div class="line">流程定义ID:HelloWorld:2:404</div><div class="line"></div><div class="line">说明：</div><div class="line">1)在数据库的act_ru_execution正在执行的执行对象表中插入一条记录</div><div class="line">2)在数据库的act_hi_procinst程实例的历史表中插入一条记录</div><div class="line">3)在数据库的act_hi_actinst活动节点的历史表中插入一条记录</div><div class="line">4)我们图中节点都是任务节点，所以同时也会在act_ru_task流程实例的历史表添加一条记录</div><div class="line">5)在数据库的act_hi_taskinst任务历史表中也插入一条记录。</div><div class="line"></div><div class="line">查询历史流程实例</div><div class="line">    </div><div class="line"> 流程实例启动以后，我们也可以对某个流程实例一共一共执行了多少次流程进行查询，因为我们本例中现在刚进行了一个流程，所以目前只能查出一个流程：</div><div class="line">``` bash</div><div class="line"> /** </div><div class="line"> * 查询历史流程实例 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findHistoryProcessInstance</span></span>()&#123;  </div><div class="line">    String processInstanceId=<span class="string">"501"</span>;  </div><div class="line">    HistoricProcessInstance hpi = processEngine.getHistoryService()  </div><div class="line">            .createHistoricProcessInstanceQuery()  </div><div class="line">            .processInstanceId(processInstanceId)  </div><div class="line">            .singleResult();  </div><div class="line">    System.out.println(hpi.getId() +<span class="string">"    "</span>+hpi.getProcessDefinitionId()+<span class="string">"   "</span>+ hpi.getStartTime()+<span class="string">"   "</span>+hpi.getDurationInMillis());  </div><div class="line">&#125;  </div><div class="line"> ``` </div><div class="line"> 运行结果：</div><div class="line">   501    HelloWorld:2:404   Fri Jun 26 09:34:51 CST 2015   null</div><div class="line"></div><div class="line">**查询当前的个人任务**</div><div class="line">在上面讲流程启动后，因为该节点是任务节点所以在任务表中插入了任务的记录，现在我们就通过办理人将任务进行下查询：</div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 查询当前的个人任务 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findMyPersonTask</span></span>() &#123;  </div><div class="line">    String assignee = <span class="string">"张三"</span>; // TODO  </div><div class="line">    List&lt;Task&gt; list = processEngine.getTaskService()// 与正在执行的任务管理相关的service  </div><div class="line">            .createTaskQuery()// 创建任务查询对象  </div><div class="line">            // 查询条件  </div><div class="line">            .taskAssignee(assignee)// 指定个人任务查询，指定办理人  </div><div class="line">            // .taskCandidateGroup(<span class="string">""</span>)//组任务的办理人查询  </div><div class="line">            // .processDefinitionId(<span class="string">""</span>)//使用流程定义ID查询  </div><div class="line">            // .processInstanceId(<span class="string">""</span>)//使用流程实例ID查询  </div><div class="line">            // .executionId(executionId)//使用执行对象ID查询  </div><div class="line">            /** 排序 */  </div><div class="line">            .orderByTaskCreateTime().asc()// 使用创建时间的升序排列  </div><div class="line">            // 返回结果集  </div><div class="line">            // .singleResult() //返回唯一的结果集  </div><div class="line">            // .count()//返回结果集的数量  </div><div class="line">            // .listPage(firstResult, maxResults)//分页查询  </div><div class="line">            .list();// 返回列表  </div><div class="line">    <span class="keyword">if</span> (list != null &amp;&amp; list.size() &gt; 0) &#123;  </div><div class="line">        <span class="keyword">for</span> (Task task : list) &#123;  </div><div class="line">            System.out.println(<span class="string">"任务ID："</span> + task.getId());  </div><div class="line">            System.out.println(<span class="string">"任务名称:"</span> + task.getName());  </div><div class="line">            System.out.println(<span class="string">"任务的创建时间:"</span> + task.getCreateTime());  </div><div class="line">            System.out.println(<span class="string">"任务的办理人:"</span> + task.getAssignee());  </div><div class="line">            System.out.println(<span class="string">"流程实例ID:"</span> + task.getProcessInstanceId());  </div><div class="line">            System.out.println(<span class="string">"执行对象ID:"</span> + task.getExecutionId());  </div><div class="line">            System.out.println(<span class="string">"流程定义ID:"</span> + task.getProcessDefinitionId());  </div><div class="line">            System.out  </div><div class="line">                    .println(<span class="string">"##################################################"</span>);  </div><div class="line">  &#125;</div></pre></td></tr></table></figure></p>
<p>运行结果：<br>任务ID：504<br>任务名称:提交申请<br>任务的创建时间:Fri Jun 2609:34:51 CST 2015<br>任务的办理人:张三<br>流程实例ID:501<br>执行对象ID:501<br>流程定义ID:HelloWorld:2:404</p>
<p>说明：<br>1)因为是任务查询，所以从processEngine中应该得到TaskService<br>2)使用TaskService获取到任务查询对象TaskQuery<br>3)为查询对象添加查询过滤条件，使用taskAssignee指定任务的办理者（即查询指定用户的代办任务），同时可以添加分页排序等过滤条件<br>4)调用list方法执行查询，返回办理者为指定用户的任务列表<br>5)任务ID、名称、办理人、创建时间可以从act_ru<em>task表中查到。<br>6)在现在这种情况下，ProcessInstance相当于Execution<br>7) 一个Task节点和Execution节点是1对1的情况，在task对象中使用Execution</em>来表示他们之间的关系<br>8)任务ID在数据库表act_ru<em>task中对应“ID</em>”列</p>
<p>完成任务<br>   查询完任务后，我们接下来将这个任务id为504的任务进行完成：<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div><div class="line">91</div><div class="line">92</div><div class="line">93</div><div class="line">94</div><div class="line">95</div><div class="line">96</div><div class="line">97</div><div class="line">98</div><div class="line">99</div><div class="line">100</div><div class="line">101</div><div class="line">102</div><div class="line">103</div><div class="line">104</div><div class="line">105</div><div class="line">106</div><div class="line">107</div><div class="line">108</div><div class="line">109</div><div class="line">110</div><div class="line">111</div><div class="line">112</div><div class="line">113</div><div class="line">114</div><div class="line">115</div><div class="line">116</div><div class="line">117</div><div class="line">118</div><div class="line">119</div><div class="line">120</div><div class="line">121</div><div class="line">122</div><div class="line">123</div><div class="line">124</div><div class="line">125</div><div class="line">126</div><div class="line">127</div><div class="line">128</div><div class="line">129</div><div class="line">130</div><div class="line">131</div><div class="line">132</div><div class="line">133</div><div class="line">134</div><div class="line">135</div><div class="line">136</div><div class="line">137</div><div class="line">138</div><div class="line">139</div><div class="line">140</div><div class="line">141</div><div class="line">142</div><div class="line">143</div><div class="line">144</div><div class="line">145</div><div class="line">146</div><div class="line">147</div><div class="line">148</div><div class="line">149</div><div class="line">150</div><div class="line">151</div><div class="line">152</div><div class="line">153</div><div class="line">154</div><div class="line">155</div><div class="line">156</div><div class="line">157</div><div class="line">158</div><div class="line">159</div><div class="line">160</div><div class="line">161</div><div class="line">162</div><div class="line">163</div><div class="line">164</div><div class="line">165</div><div class="line">166</div><div class="line">167</div><div class="line">168</div><div class="line">169</div></pre></td><td class="code"><pre><div class="line"> /** </div><div class="line"> * 完成我的任务 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">compliteMyPersonTask</span></span>() &#123;  </div><div class="line">    // 任务ID  </div><div class="line">    String taskId = <span class="string">"504"</span>;  </div><div class="line">    processEngine.getTaskService().complete(taskId);  </div><div class="line">    ;  </div><div class="line">    System.out.println(<span class="string">"完成任务：任务ID:"</span> + taskId);  </div><div class="line">&#125;  </div><div class="line"></div><div class="line">``` </div><div class="line"> 运行结果：</div><div class="line">完成任务：任务ID:504</div><div class="line">说明：</div><div class="line">1)是完成任务，所以从ProcessEngine得到的是TaskService。</div><div class="line">2)当执行完这段代码，再以员工的身份去执行查询的时候，会发现这个时候已经没有数据了，因为正在执行的任务中没有数据。</div><div class="line">3)对于执行完的任务，activiti将从act_ru_task表中删除该任务，下一个任务会被插入进来。</div><div class="line">4)以”部门经理”的身份进行查询，可以查到结果。因为流程执行到部门经理审批这个节点了。</div><div class="line">5)再执行办理任务代码，执行完以后以”部门经理”身份进行查询，没有结果。</div><div class="line">6)重复第3和4步直到流程执行完。</div><div class="line"></div><div class="line">**查询历史任务**</div><div class="line">员工张三的任务已经完成，现在任务到部门经理李四了，如果我们现在仍然查询张三的任务的话，自然是查询不到了，只有查询李四才可以查到，不过我们可以通过流程实例id查询历史任务，查询历史任务可以将已经办理过的任务和现在正在执行的任务都查询出来：</div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 查询历史任务 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findHistoryTask</span></span>()&#123;  </div><div class="line">    String processInstanceId=<span class="string">"501"</span>;  </div><div class="line">    List&lt;HistoricTaskInstance&gt; list = processEngine.getHistoryService()//与历史数据（历史表）相关的service  </div><div class="line">            .createHistoricTaskInstanceQuery()//创建历史任务实例查询  </div><div class="line">            .processInstanceId(processInstanceId)  </div><div class="line">//              .taskAssignee(taskAssignee)//指定历史任务的办理人  </div><div class="line">            .list();  </div><div class="line">    <span class="keyword">if</span>(list!=null &amp;&amp; list.size()&gt;0)&#123;  </div><div class="line">        <span class="keyword">for</span>(HistoricTaskInstance hti:list)&#123;  </div><div class="line">            System.out.println(hti.getId()+<span class="string">"    "</span>+hti.getName()+<span class="string">"    "</span>+hti.getProcessInstanceId()+<span class="string">"   "</span>+hti.getStartTime()+<span class="string">"   "</span>+hti.getEndTime()+<span class="string">"   "</span>+hti.getDurationInMillis());  </div><div class="line">            System.out.println(<span class="string">"################################"</span>);  </div><div class="line">        &#125;  </div><div class="line">    &#125;     </div><div class="line">  </div><div class="line">&#125;  </div><div class="line">``` </div><div class="line"> 运行结果：</div><div class="line"></div><div class="line">504    提交申请   501   Fri Jun 26 09:34:51 CST2015   Fri Jun 26 09:50:50 CST 2015   959867</div><div class="line"></div><div class="line">602    审批【部门经理】   501   Fri Jun 26 09:50:51 CST2015   null   null</div><div class="line"></div><div class="line"> </div><div class="line"></div><div class="line">查询流程是否结束</div><div class="line">  我们还可以通过流程实例id查询某个流程现在的状态，是仍然在执行过程中呢，还是流程执行已经结束：</div><div class="line">``` bash</div><div class="line">  /** </div><div class="line"> * 查询流程状态（判断流程正在执行，还是结束） </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">isProcessEnd</span></span>()&#123;  </div><div class="line">String processInstanceId =  <span class="string">"501"</span>;  </div><div class="line">ProcessInstance pi = processEngine.getRuntimeService()//表示正在执行的流程实例和执行对象  </div><div class="line">    .createProcessInstanceQuery()//创建流程实例查询  </div><div class="line">    .processInstanceId(processInstanceId)//使用流程实例ID查询  </div><div class="line">    .singleResult();  </div><div class="line">      </div><div class="line"><span class="keyword">if</span>(pi==null)&#123;  </div><div class="line">System.out.println(<span class="string">"流程已经结束"</span>);  </div><div class="line">&#125;  </div><div class="line"><span class="keyword">else</span>&#123;  </div><div class="line">System.out.println(<span class="string">"流程没有结束"</span>);  </div><div class="line">&#125;  </div><div class="line">      </div><div class="line">&#125;</div><div class="line">``` </div><div class="line"></div><div class="line"><span class="comment">### 流程变量</span></div><div class="line"> 流程变量与我们平常理解的变量是一样的，只不过是用在了我们activiti中，所以称为流程变量，流程变量在整个工作流扮演着很重要的角色。</div><div class="line"> 例如，请假流程中有请假天数、请假原因等一些参数都是流程变量使用的范围，流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不互相影响的。流程实例结束完成以后流程变量还保存在数据库中（存放在流程变量的历史表中）。</div><div class="line"></div><div class="line">``` bash</div><div class="line"> &lt;?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?&gt;  </div><div class="line">&lt;definitions xmlns=<span class="string">"http://www.omg.org/spec/BPMN/20100524/MODEL"</span> xmlns:xsi=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span> xmlns:xsd=<span class="string">"http://www.w3.org/2001/XMLSchema"</span> xmlns:activiti=<span class="string">"http://activiti.org/bpmn"</span> xmlns:bpmndi=<span class="string">"http://www.omg.org/spec/BPMN/20100524/DI"</span> xmlns:omgdc=<span class="string">"http://www.omg.org/spec/DD/20100524/DC"</span> xmlns:omgdi=<span class="string">"http://www.omg.org/spec/DD/20100524/DI"</span> typeLanguage=<span class="string">"http://www.w3.org/2001/XMLSchema"</span> expressionLanguage=<span class="string">"http://www.w3.org/1999/XPath"</span> targetNamespace=<span class="string">"http://www.activiti.org/test"</span>&gt;  </div><div class="line">  &lt;process id=<span class="string">"processVariables"</span> name=<span class="string">"processVariables【流程请假】"</span> isExecutable=<span class="string">"true"</span>&gt;  </div><div class="line">    &lt;startEvent id=<span class="string">"startevent1"</span> name=<span class="string">"Start"</span>&gt;&lt;/startEvent&gt;  </div><div class="line">    &lt;endEvent id=<span class="string">"endevent1"</span> name=<span class="string">"End"</span>&gt;&lt;/endEvent&gt;  </div><div class="line">    &lt;userTask id=<span class="string">"usertask1"</span> name=<span class="string">"提交申请"</span>&gt;&lt;/userTask&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow1"</span> sourceRef=<span class="string">"startevent1"</span> targetRef=<span class="string">"usertask1"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">    &lt;userTask id=<span class="string">"usertask2"</span> name=<span class="string">"审批【总经理】"</span> activiti:assignee=<span class="string">"王二"</span>&gt;&lt;/userTask&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow2"</span> sourceRef=<span class="string">"usertask1"</span> targetRef=<span class="string">"usertask2"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">    &lt;sequenceFlow id=<span class="string">"flow3"</span> sourceRef=<span class="string">"usertask2"</span> targetRef=<span class="string">"endevent1"</span>&gt;&lt;/sequenceFlow&gt;  </div><div class="line">  &lt;/process&gt;  </div><div class="line">  &lt;bpmndi:BPMNDiagram id=<span class="string">"BPMNDiagram_processVariables"</span>&gt;  </div><div class="line">    &lt;bpmndi:BPMNPlane bpmnElement=<span class="string">"processVariables"</span> id=<span class="string">"BPMNPlane_processVariables"</span>&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"startevent1"</span> id=<span class="string">"BPMNShape_startevent1"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"35.0"</span> width=<span class="string">"35.0"</span> x=<span class="string">"350.0"</span> y=<span class="string">"90.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"endevent1"</span> id=<span class="string">"BPMNShape_endevent1"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"35.0"</span> width=<span class="string">"35.0"</span> x=<span class="string">"350.0"</span> y=<span class="string">"420.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"usertask1"</span> id=<span class="string">"BPMNShape_usertask1"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"55.0"</span> width=<span class="string">"105.0"</span> x=<span class="string">"315.0"</span> y=<span class="string">"190.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNShape bpmnElement=<span class="string">"usertask2"</span> id=<span class="string">"BPMNShape_usertask2"</span>&gt;  </div><div class="line">        &lt;omgdc:Bounds height=<span class="string">"55.0"</span> width=<span class="string">"105.0"</span> x=<span class="string">"315.0"</span> y=<span class="string">"300.0"</span>&gt;&lt;/omgdc:Bounds&gt;  </div><div class="line">      &lt;/bpmndi:BPMNShape&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow1"</span> id=<span class="string">"BPMNEdge_flow1"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"367.0"</span> y=<span class="string">"125.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"367.0"</span> y=<span class="string">"190.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow2"</span> id=<span class="string">"BPMNEdge_flow2"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"367.0"</span> y=<span class="string">"245.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"367.0"</span> y=<span class="string">"300.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">      &lt;bpmndi:BPMNEdge bpmnElement=<span class="string">"flow3"</span> id=<span class="string">"BPMNEdge_flow3"</span>&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"367.0"</span> y=<span class="string">"355.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">        &lt;omgdi:waypoint x=<span class="string">"367.0"</span> y=<span class="string">"420.0"</span>&gt;&lt;/omgdi:waypoint&gt;  </div><div class="line">      &lt;/bpmndi:BPMNEdge&gt;  </div><div class="line">    &lt;/bpmndi:BPMNPlane&gt;  </div><div class="line">  &lt;/bpmndi:BPMNDiagram&gt;  </div><div class="line">&lt;/definitions&gt;   </div><div class="line"></div><div class="line">``` </div><div class="line"></div><div class="line"> 部署流程定义：</div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 部署流程定义（从inputStream） </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">deploymentProcessDefinition_inputStream</span></span>() &#123;  </div><div class="line">ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();  </div><div class="line">InputStream inputStreamBpmn = this.getClass().getResourceAsStream(  </div><div class="line">    <span class="string">"/diagrams/processVariables.bpmn"</span>);  </div><div class="line">InputStream inputStreamPng = this.getClass().getResourceAsStream(  </div><div class="line">    <span class="string">"/diagrams/processVariables.png"</span>);  </div><div class="line">Deployment deployment = processEngine.getRepositoryService()// 与流程定义和部署对象相关的Service  </div><div class="line">    .createDeployment()// 创建一个部署对象  </div><div class="line">    .name(<span class="string">"流程定义"</span>)// 添加部署名称  </div><div class="line">    .addInputStream(<span class="string">"processVariables.bpmn"</span>, inputStreamBpmn)// 使用资源文件的名称（要求:与资源文件的名称要一致），和输入流完成部署  </div><div class="line">    .addInputStream(<span class="string">"processVariables.png"</span>, inputStreamPng)// 使用资源文件的名称(要求:与资源文件的名称要一致)，和输入流完成部署  </div><div class="line">    .deploy();// 完成部署  </div><div class="line">System.out.println(<span class="string">"部署ID："</span> + deployment.getId());  </div><div class="line">System.out.println(<span class="string">"部署名称："</span> + deployment.getName());  </div><div class="line">&#125;  </div><div class="line">``` </div><div class="line"> 运行结果：</div><div class="line"> </div><div class="line">部署ID：701</div><div class="line">部署名称：流程定义</div><div class="line"></div><div class="line">**启动流程实例:**</div><div class="line">``` bash</div><div class="line"> /** </div><div class="line">     * 启动流程实例 </div><div class="line">     */  </div><div class="line">    @Test  </div><div class="line">    public void <span class="function"><span class="title">startProcessInstance</span></span>() &#123;  </div><div class="line">        // 流程定义的key  </div><div class="line">        String processDefinitionKey = <span class="string">"processVariables"</span>;  </div><div class="line">        ProcessInstance pi = processEngine.getRuntimeService()// 与正在执行的流程实例和执行对象相关的service  </div><div class="line">                .startProcessInstanceByKey(processDefinitionKey);// 使用流程定义的key启动流程实例，key对应processVariables文件中的id的属性值，使用key值启动，默认是按照最新版本进行启动  </div><div class="line">System.out.println(<span class="string">"流程实例ID："</span> + pi.getId());  </div><div class="line">System.out.println(<span class="string">"流程定义ID："</span> + pi.getProcessDefinitionId());  </div><div class="line">System.out.println(<span class="string">"流程实例ID"</span> + pi.getProcessInstanceId());  </div><div class="line">  </div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>运行结果：<br>流程实例ID：801<br>流程定义ID：processVariables:1:704<br>流程实例ID801</p>
<p><strong>查询任务</strong><br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div></pre></td><td class="code"><pre><div class="line">/** </div><div class="line"> * 查询任务通过流程实例id </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">findTask</span></span>()&#123;  </div><div class="line">    String processInstanceId=<span class="string">"801"</span>;  </div><div class="line">    List&lt;HistoricTaskInstance&gt; list = processEngine.getHistoryService()//与历史数据（历史表）相关的service  </div><div class="line">            .createHistoricTaskInstanceQuery()//创建历史任务实例查询  </div><div class="line">            .processInstanceId(processInstanceId)  </div><div class="line">            .list();  </div><div class="line">    <span class="keyword">if</span>(list!=null &amp;&amp; list.size()&gt;0)&#123;  </div><div class="line">        <span class="keyword">for</span>(HistoricTaskInstance hti:list)&#123;  </div><div class="line">            System.out.println(hti.getId()+<span class="string">"    "</span>+hti.getName()+<span class="string">"    "</span>+hti.getProcessInstanceId()+<span class="string">"   "</span>+hti.getStartTime()+<span class="string">"   "</span>+hti.getEndTime()+<span class="string">"   "</span>+hti.getDurationInMillis());  </div><div class="line">            System.out.println(<span class="string">"################################"</span>);  </div><div class="line">        &#125;  </div><div class="line">    &#125;     </div><div class="line">&#125;  </div><div class="line">``` </div><div class="line"></div><div class="line"> 运行结果：</div><div class="line">804    提交申请   801   Fri Jun 26 10:55:02 CST2015   null   null</div><div class="line"></div><div class="line">关于部署流程定义、启动流程实例和查询正在办理的任务我们前面的文章已经介绍过了，所以我们不再详细介绍，下面开始我们的设置流程变量，设置流程变量我们这里提供了两种方式，分别是使用基本数据类型和使用javabean的方法，同意获取流程变量也是不一样的：</div><div class="line"></div><div class="line">**设置流程变量**</div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 设置流程变量 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">setVariables</span></span>() &#123;  </div><div class="line">// 与任务相关的service,正在执行的service  </div><div class="line">TaskService taskService = processEngine.getTaskService();  </div><div class="line"></div><div class="line">// 任务ID  </div><div class="line">String taskId = <span class="string">"804"</span>;  </div><div class="line"></div><div class="line">// 1.设置流程变量，使用基本数据类型  </div><div class="line">taskService.setVariable(taskId, <span class="string">"请假天数"</span>, 7);// 与任务ID邦德  </div><div class="line">taskService.setVariable(taskId, <span class="string">"请假日期"</span>, new Date());  </div><div class="line">taskService.setVariableLocal(taskId, <span class="string">"请假原因"</span>, <span class="string">"回去探亲，一起吃个饭123"</span>);  </div><div class="line"></div><div class="line">System.out.println(<span class="string">"设置流程变量成功！"</span>);  </div><div class="line">  </div><div class="line">&#125;  </div><div class="line">``` </div><div class="line"></div><div class="line">运行结果：</div><div class="line"> </div><div class="line"> 设置流程变量成功！</div><div class="line">**获取流程变量**</div><div class="line">``` bash</div><div class="line">/** </div><div class="line"> * 获取流程变量 </div><div class="line"> */  </div><div class="line">@Test  </div><div class="line">public void <span class="function"><span class="title">getVariables</span></span>() &#123;  </div><div class="line">    // 与任务（正在执行的service）  </div><div class="line">    TaskService taskService = processEngine.getTaskService();  </div><div class="line">    // 任务Id  </div><div class="line">    String taskId = <span class="string">"804"</span>;  </div><div class="line">    // 1.获取流程变量，使用基本数据类型  </div><div class="line">    Integer days = (Integer) taskService.getVariable(taskId, <span class="string">"请假天数"</span>);  </div><div class="line">    Date date = (Date) taskService.getVariable(taskId, <span class="string">"请假日期"</span>);  </div><div class="line">    String reason = (String) taskService.getVariable(taskId, <span class="string">"请假原因"</span>);  </div><div class="line">  </div><div class="line">System.out.println(<span class="string">"请假天数："</span> + days);  </div><div class="line">System.out.println(<span class="string">"请假日期："</span> + date);  </div><div class="line">System.out.println(<span class="string">"请假原因："</span> + reason);  </div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p> 运行结果：</p>
<p>请假天数：7<br>请假日期：Fri Jun 2611:07:28 CST 2015<br>请假原因：回去探亲，一起吃个饭123</p>
<p><strong>使用javabean JavaBean的Person类</strong></p>
<pre><code class="bash">package com.tgb;  

import java.io.Serializable;  
import java.util.Date;  

public class Person implements Serializable {  

private static final long serialVersionUID = 361866001729020143L;  
//请假天数  
private int id;  
//请假人  
private String name;  
//请假原因  
private String note;  
//请假时间  
private Date date;  
public Date <span class="function"><span class="title">getDate</span></span>() {  
<span class="built_in">return</span> date;  
}  
public void <span class="function"><span class="title">setDate</span></span>() {  
this.date = new Date();  
}  
public String <span class="function"><span class="title">getNote</span></span>() {  
<span class="built_in">return</span> note;  
}  
public void setNote(String note) {  
this.note = note;  
}  
public int <span class="function"><span class="title">getId</span></span>() {  
<span class="built_in">return</span> id;  
}  
public void setId(int id) {  
this.id = id;  
}  
public String <span class="function"><span class="title">getName</span></span>() {  
<span class="built_in">return</span> name;  
}  
public void setName(String name) {  
this.name = name;  
}  
}
</code></pre>
<p> <strong>设置流程变量</strong></p>
<pre><code class="bash">/** 
 * 设置流程变量 
 */  
@Test  
public void <span class="function"><span class="title">setVariables</span></span>() {  
    // 与任务相关的service,正在执行的service  
TaskService taskService = processEngine.getTaskService();  

// 任务ID  
String taskId = <span class="string">"804"</span>;  

// 设置流程变量，使用javaBean方法  
/** 
* 当一个javaBean(实现序列号)放置到流程变量中，要求javabean的属性不能在发生变化 如果发生变化，再获取时，抛出异常 
*  
* 解决方案：在person对象中添加： private static final long 
* serialVersionUID=<span class="string">"6757393795687480331L"</span>; 同时实现序列号接口 
*  
*/  
Person p = new Person();  
p.setName(<span class="string">"翠花"</span>);  
p.setId(20);  
p.setDate();;  
p.setNote(<span class="string">"回去探亲，一起吃个饭123"</span>);  
taskService.setVariable(taskId, <span class="string">"人员信息(添加固定版本)"</span>, p);  

System.out.println(<span class="string">"设置流程变量成功！"</span>);  

}
</code></pre>
<p>运行结果：<br>   设置流程变量成功</p>
<p><strong>获取流程变量</strong></p>
<pre><code class="bash">/** 
 * 获取流程变量 
 */  
@Test  
public void <span class="function"><span class="title">getVariables</span></span>() {  
// 与任务（正在执行的service）  
TaskService taskService = processEngine.getTaskService();  
// 任务Id  
String taskId = <span class="string">"804"</span>;  

// 2.获取流程变量，使用javaBean类型  
Person p = (Person)taskService.getVariable(taskId, <span class="string">"人员信息(添加固定版本)"</span>);  
System.out.println(<span class="string">" 请假人：  "</span>+p.getName()+<span class="string">"  请假天数：  "</span>+p.getId()+<span class="string">"   请假时间："</span>+ p.getDate()+ <span class="string">"   请假原因： "</span>+p.getNote());  

}
</code></pre>
<p>运行结果<br>   请假人： 翠花  请假天数：  20  请假时间：Fri Jun 26 11:13:44 CST 2015  请假原因： 回去探亲，一起吃个饭123</p>
<p><strong>查询历史流程变量</strong><br>可以根据变量名称查询该变量的所有历史信息</p>
<pre><code class="bash">可以根据变量名称查询该变量的所有历史信息  
/** 
 * 查询流程变量的历史表 
 */  
@Test  
public void <span class="function"><span class="title">findHistoryProcessVariables</span></span>(){  
    List&lt;HistoricVariableInstance&gt; list = processEngine.getHistoryService()  
            .createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询对象  
            .variableName(<span class="string">"请假原因"</span>)  
            .list();  
    <span class="keyword">if</span> (list!=null &amp;&amp;list.size()&gt;0) {  
        <span class="keyword">for</span> (HistoricVariableInstance hvi : list) {  
            System.out.println(hvi.getId()+<span class="string">"     "</span>+hvi.getProcessInstanceId()+<span class="string">"   "</span>+hvi.getVariableName()  
                    +<span class="string">"   "</span>+hvi.getVariableTypeName()+<span class="string">"    "</span>+hvi.getValue());  
            System.out.println(<span class="string">"########################################"</span>);  
        }  
    }  

}
</code></pre>
<p> 流程变量支持的数据类型：<br>   流程变量支持的数据类型包括：TypeName、string、integer、short、long、double、boolean、data、binary、serializable，我们可以看出流程变量支持的包括了大部分封装类型和Date、String和实现了Serializable接口的类的类型。</p>

        </div>

        <blockquote class="post-copyright">
    <div class="content">
        
<span class="post-time">
    最后更新时间：<time datetime="2017-08-18T06:14:29.826Z" itemprop="dateUpdated">2017年8月18日 14:14</time>
</span><br>


        如要转载请注明出处：<a href="/2017/08/17/activity/" target="_blank" rel="external">http://fish_08.oschina.io/2017/08/17/activity/</a>
    </div>
    <footer>
        <a href="http://fish_08.oschina.io">
            <img src="/img/avatar.jpg" alt="于亮">
            于亮
        </a>
    </footer>
</blockquote>

        
<div class="page-reward">
    <a id="rewardBtn" href="javascript:;" class="page-reward-btn waves-effect waves-circle waves-light">赏</a>
</div>



        <div class="post-footer">
            
	<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Activiti/">Activiti</a></li></ul>


            
<div class="page-share-wrap">
    

<div class="page-share" id="pageShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://fish_08.oschina.io/2017/08/17/activity/&title=《Activiti》 — 尼古拉斯-鱼丸博客&pic=http://fish_08.oschina.io/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://fish_08.oschina.io/2017/08/17/activity/&title=《Activiti》 — 尼古拉斯-鱼丸博客&source=" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://fish_08.oschina.io/2017/08/17/activity/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《Activiti》 — 尼古拉斯-鱼丸博客&url=http://fish_08.oschina.io/2017/08/17/activity/&via=http://fish_08.oschina.io" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://fish_08.oschina.io/2017/08/17/activity/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>



    <a href="javascript:;" id="shareFab" class="page-share-fab waves-effect waves-circle">
        <i class="icon icon-share-alt icon-lg"></i>
    </a>
</div>



        </div>
    </div>

    
<nav class="post-nav flex-row flex-justify-between">
  
    <div class="waves-block waves-effect prev">
      <a href="/2017/08/29/meipro-file/" id="post-prev" class="post-nav-link">
        <div class="tips"><i class="icon icon-angle-left icon-lg icon-pr"></i> Prev</div>
        <h4 class="title">美办集成GFS文件服务</h4>
      </a>
    </div>
  

  
    <div class="waves-block waves-effect next">
      <a href="/2017/07/26/SpringCloud服务容错保护Hystrix监控数据聚合/" id="post-next" class="post-nav-link">
        <div class="tips">Next <i class="icon icon-angle-right icon-lg icon-pl"></i></div>
        <h4 class="title">SpringCloud服务容错保护Hystrix监控数据聚合</h4>
      </a>
    </div>
  
</nav>



    







</article>

<div id="reward" class="page-modal reward-lay">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <h3 class="reward-title">
        <i class="icon icon-quote-left"></i>
        谢谢包子~
        <i class="icon icon-quote-right"></i>
    </h3>
    <ul class="reward-items">
        
        <li>
            <img src="/img/wechat.png" title="微信打赏二维码" alt="微信打赏二维码">
            <p>微信</p>
        </li>
        

        
        <li>
            <img src="/img/alipay.png" title="支付宝打赏二维码" alt="支付宝打赏二维码">
            <p>支付宝</p>
        </li>
        
    </ul>
</div>



</div>

        <footer class="footer">
    <div class="top">
        
<p>
    <span id="busuanzi_container_site_uv" style='display:none'>
        站点总访客数：<span id="busuanzi_value_site_uv"></span>
    </span>
    <span id="busuanzi_container_site_pv" style='display:none'>
        站点总访问量：<span id="busuanzi_value_site_pv"></span>
    </span>
</p>


        <p>
            <span><a href="/atom.xml" target="_blank" class="rss" title="rss"><i class="icon icon-lg icon-rss"></i></a></span>
            <span>博客内容遵循 <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">知识共享 署名 - 非商业性 - 相同方式共享 4.0协议</a></span>
        </p>
    </div>
    <div class="bottom">
        <p>
            <span>Power by <a href="http://hexo.io/" target="_blank">Hexo</a> Theme <a href="http://fish_08.oschina.io/" target="_blank">yuliang</a></span>
            <span>尼古拉斯-鱼丸博客 &copy; 2015 - 2018</span>
        </p>
    </div>
</footer>

    </main>
    <div class="mask" id="mask"></div>
<a href="javascript:;" id="gotop" class="waves-effect waves-circle waves-light"><span class="icon icon-lg icon-chevron-up"></span></a>



<div class="global-share" id="globalShare">
    <ul class="reset share-icons">
      <li>
        <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://fish_08.oschina.io/2017/08/17/activity/&title=《Activiti》 — 尼古拉斯-鱼丸博客&pic=http://fish_08.oschina.io/img/avatar.jpg" data-title="微博">
          <i class="icon icon-weibo"></i>
        </a>
      </li>
      <li>
        <a class="weixin share-sns wxFab" href="javascript:;" data-title="微信">
          <i class="icon icon-weixin"></i>
        </a>
      </li>
      <li>
        <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://fish_08.oschina.io/2017/08/17/activity/&title=《Activiti》 — 尼古拉斯-鱼丸博客&source=" data-title=" QQ">
          <i class="icon icon-qq"></i>
        </a>
      </li>
      <li>
        <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://fish_08.oschina.io/2017/08/17/activity/" data-title=" Facebook">
          <i class="icon icon-facebook"></i>
        </a>
      </li>
      <li>
        <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《Activiti》 — 尼古拉斯-鱼丸博客&url=http://fish_08.oschina.io/2017/08/17/activity/&via=http://fish_08.oschina.io" data-title=" Twitter">
          <i class="icon icon-twitter"></i>
        </a>
      </li>
      <li>
        <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://fish_08.oschina.io/2017/08/17/activity/" data-title=" Google+">
          <i class="icon icon-google-plus"></i>
        </a>
      </li>
    </ul>
 </div>


<div class="page-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;"><i class="icon icon-close"></i></a>
    <p>扫一扫，分享到微信</p>
    <img src="" alt="微信分享二维码">
</div>




    <script src="//cdn.bootcss.com/node-waves/0.7.4/waves.min.js"></script>
<script>
var BLOG = { ROOT: '/', SHARE: true, REWARD: true };



</script>

<script src="/js/main.min.js?v=1.6.7"></script>


<div class="search-panel" id="search-panel">
    <ul class="search-result" id="search-result"></ul>
</div>
<template id="search-tpl">
<li class="item">
    <a href="{path}" class="waves-block waves-effect">
        <div class="title ellipsis" title="{title}">{title}</div>
        <div class="flex-row flex-middle">
            <div class="tags ellipsis">
                {tags}
            </div>
            <time class="flex-col time">{date}</time>
        </div>
    </a>
</li>
</template>

<script src="/js/search.min.js?v=1.6.7" async></script>






<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>


</body>
</html>
